#include "client.h"

char* local_path="/home/yu/project/client";

void clean(){
    int ch;
    while((ch = getchar()) != '\n' && ch != EOF);
}

int main(int argc, char *argv[])
{
    ARGS_CHECK(argc,3);
    int sockfd=connectTcp(argv[1],argv[2]);

    //连接成功
    char username[50];
    char password[50];
    int user_choice;
    int flag=0;//判断用户是否要选择

    printf("网盘欢迎您！\n");
    while(1){
        if(flag==0){
            printf("选择注册(0)还是登录(1),请输入0或1：");
            scanf("%d",&user_choice);
            clean();
        }
        if(user_choice != 0 && user_choice != 1){
            printf("你的选择错误，请重新选择\n");
            fflush(stdout);
            continue;
        }
        printf("请输入用户名：");
        fflush(stdout);
        fgets(username, sizeof(username), stdin);
        username[strcspn(username, "\n")] = '\0';

        printf("请输入密码: ");
        fflush(stdout);
        get_password(password, sizeof(password));

        if(user_choice == 0){
            int  ret = register_user(sockfd,username,password);
            if(ret == 0){//注册成功
                flag=1;
                user_choice=1;//选择直接登录
                continue;
            }else if(ret==-1){//用户已存在
                flag=1;
                user_choice=1;//选择直接登录
                continue;
            }else if(ret==-2){//格式错误
                flag=0;//重新选择登录还是注册
                continue;
            }
        }else{
            int ret = log_in(sockfd,username,password);
            printf("login success: ret = %d\n",ret);
            if(ret == 0){//登录成功
                break;
            }else if(ret==-1){
                flag=0;//重新选择注册还是登录
                continue;
            }else if(ret==-2){//密码错误
                flag=1;
                user_choice=1;//重新登录
                continue;
            }else if(ret==-3){//重新选择注册还是登录
                flag=0;
                continue;
            }
        }
    }
    //登录成功以后接收token
    train_t token;
    bzero(&token,sizeof(train_t));
    recvn(sockfd,&token.type,sizeof(token.type));
    if(token.type==USER_TOKEN){//接收服务端发送的token
        recvn(sockfd,&token.length,sizeof(token.length));
        recvn(sockfd,&token.data,token.length);
    }

    int netfd;//存储客户端连接到服务端的netfd
    recvn(sockfd,&netfd,sizeof(int));

    pthread_t puts_pid;//上传线程
    pthread_t gets_pid;//下载线程
    char curr_path[1024];//当前目录
    snprintf(curr_path, sizeof(curr_path),"%s@localhost:~$ ", username);//用户根目录

    help();
    while(1){
        train_t cmds;//发送命令小火车
        char buf[1024];//存放键盘输入的命令
        bzero(buf, sizeof(buf));
        bzero(&cmds, sizeof(train_t));

        printf("%s",curr_path);//每次重新输入命令都显示当前路径
        scanf(" %[^\n]", buf);//获取键盘输入

        char *p=strtok(buf," ");//解析命令前半部分
        if(strcmp(p,"cd")==0){
            cmds.type=CMD_CD;
            p=strtok(NULL,"\0");
            if(p!=NULL){//cd后面有字符串
                strcpy(cmds.data, p);
                printf("cmds.data = %s\n", cmds.data);
                
                cmds.length=strlen(p);
                send(sockfd, &cmds, sizeof(cmds.type)+ sizeof(cmds.length)+ cmds.length, 0);

                bzero(&cmds, sizeof(train_t));
                recvn(sockfd,&cmds.type,sizeof(cmds.type));
                recvn(sockfd,&cmds.length,sizeof(cmds.length));
                recvn(sockfd,&cmds.data,cmds.length);
                if(cmds.type==SEND_TIP){//错误信息
                    printf("%s\n", cmds.data);
                }else if(cmds.type==SEND_URL){//cd成功进入目录
                    snprintf(curr_path, sizeof(curr_path),"%s@localhost:%s$ ",username, cmds.data);
                }
                continue;
            }else if(p==NULL){
                snprintf(curr_path, sizeof(curr_path), "%s@localhost:~$", username);//回到家目录
            }
            else{//指令错误
                printf("指令错误\n");
                continue;
            }

        }else if(strcmp(p,"ls")==0){
            cmds.type = CMD_LS;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                strcpy(cmds.data,p);
                cmds.length=strlen(p);
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
            }else{
                cmds.length=0;//ls后面没有参数,发空data给服务端
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
            }
            bzero(&cmds, sizeof(train_t));
            recvn(sockfd,&cmds.type,sizeof(cmds.type));
            recvn(sockfd,&cmds.length,sizeof(cmds.length));
            recvn(sockfd,&cmds.data,cmds.length);
            printf("%s\n", cmds.data);
            continue;

        }else if(strcmp(p,"pwd")==0){
            cmds.type=CMD_PWD;
            cmds.length=0;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                printf("指令错误\n");
                continue;
            }
            send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
            bzero(&cmds, sizeof(train_t));
            recvn(sockfd,&cmds.type,sizeof(cmds.type));
            recvn(sockfd,&cmds.length,sizeof(cmds.length));
            recvn(sockfd,&cmds.data,cmds.length);
            printf("%s\n",cmds.data);
            continue;

        }else if(strcmp(p,"puts")==0){//上传
            thread_t thread;
            bzero(&thread,sizeof(thread_t));
            thread.ip=argv[1];
            thread.port=argv[2];
            thread.username=username;
            thread.token=token.data;
            thread.netfd=netfd;
            thread.cmds.type=CMD_PUTS;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                strcpy(thread.cmds.data,p);
                thread.cmds.length=strlen(p);
                pthread_create(&puts_pid, NULL,threadFunc_puts,&thread);
                continue;
            }else{//puts后面没有参数
                printf("指令错误\n");
                continue;
            }

        }else if(strcmp(p,"gets")==0){//下载
            thread_t thread;
            bzero(&thread,sizeof(thread_t));
            thread.ip=argv[1];
            thread.port=argv[2];
            thread.username=username;
            thread.token=token.data;
            thread.netfd=netfd;
            thread.cmds.type=CMD_GETS;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                strcpy(thread.cmds.data,p);
                thread.cmds.length=strlen(p);
                pthread_create(&gets_pid,NULL,threadFunc_gets,&thread);
                continue;
            }else{//gets后面没有参数
                printf("指令错误\n");
                continue;
            }

        }else if(strcmp(p,"remove")==0){
            cmds.type=CMD_REMOVE;
            p=strtok(NULL,"\0");
            if(p!=NULL){
                strcpy(cmds.data,p);
                cmds.length=strlen(p);
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
                bzero(&cmds, sizeof(train_t));
                recvn(sockfd,&cmds.type,sizeof(cmds.type));
                recvn(sockfd,&cmds.length,sizeof(cmds.length));
                recvn(sockfd,&cmds.data,cmds.length);
                printf("%s\n", cmds.data);
                continue;
            }else{//remove后面没有参数
                printf("指令错误\n");
                continue;
            }

        }else if(strcmp(p,"mkdir")==0){
            cmds.type=CMD_MKDIR;
            p=strtok(NULL,"\0");
            if(p==NULL){
                printf("指令错误\n");
                continue;
            }
            cmds.length=strlen(p);
            strcpy(cmds.data, p);
            send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
            bzero(&cmds, sizeof(train_t));
            recvn(sockfd,&cmds.type,sizeof(cmds.type));
            recvn(sockfd,&cmds.length,sizeof(cmds.length));
            recvn(sockfd,&cmds.data,cmds.length);
            printf("%s\n", cmds.data);
            continue;

        }else if(strcmp(p,"rmdir")==0){
            cmds.type=CMD_RMDIR;
            p=strtok(NULL,"\0");
            if(p==NULL){
                printf("指令错误\n");
                continue;
            }
            cmds.length=strlen(p);
            strcpy(cmds.data, p);
            send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
            bzero(&cmds, sizeof(train_t));
            recvn(sockfd,&cmds.type,sizeof(cmds.type));
            recvn(sockfd,&cmds.length,sizeof(cmds.length));
            recvn(sockfd,&cmds.data,cmds.length);
            printf("%s\n", cmds.data);
            continue;

        }else if(strcmp(p,"help")==0){
            p=strtok(NULL,"\0");
            if(p!=NULL) printf("指令错误\n");
            help();
            continue;

        }else if(strcmp(p,"history")==0){
            cmds.type=CMD_HISTORY;
            cmds.length=0;
            p=strtok(NULL,"\0");
            if(p==NULL){
                send(sockfd,&cmds,sizeof(cmds.type)+sizeof(cmds.length)+cmds.length,0);
                bzero(&cmds, sizeof(train_t));
                recvn(sockfd,&cmds.type,sizeof(cmds.type));
                recvn(sockfd,&cmds.length,sizeof(cmds.length));
                recvn(sockfd,&cmds.data,cmds.length);
                printf("%s\n",cmds.data);
                continue;
            }else{
                printf("指令错误\n");
                continue;
            }
        }else if(strcmp(p,"local_ls")==0){
            show_client_files(local_path);
        }
    }
    pthread_join(puts_pid, NULL); // 等待线程结束
    pthread_join(gets_pid, NULL); // 等待线程结束
    close(sockfd);
    return 0;
}

